package com.imyuanma.qingyun.common.config.security;

import com.imyuanma.qingyun.interfaces.ums.model.SsoVerifyDTO;
import org.springframework.security.authentication.AbstractAuthenticationToken;
import org.springframework.security.core.userdetails.UserDetails;

import javax.security.auth.Subject;
import java.util.stream.Collectors;

/**
 * sso认证token
 *
 * @author wangjy
 * @date 2022/07/16 13:46:20
 */
public class SsoAuthenticationToken extends AbstractAuthenticationToken {
    /**
     * sso验证信息
     */
    private SsoVerifyDTO ssoVerifyDTO;
    /**
     * 用户详情
     */
    private UserDetails userDetails;

    public SsoAuthenticationToken(SsoVerifyDTO ssoVerifyDTO) {
        super(ssoVerifyDTO.getResourceCodeList() == null ? null : ssoVerifyDTO.getResourceCodeList().stream().map(ResourceGrantedAuthority::new).collect(Collectors.toList()));
        this.ssoVerifyDTO = ssoVerifyDTO;
        this.userDetails = DefaultUserDetails.newInstance(ssoVerifyDTO.getLoginUser(), ssoVerifyDTO.getToken());
    }

    public SsoVerifyDTO getSsoVerifyDTO() {
        return ssoVerifyDTO;
    }

    public UserDetails getUserDetails() {
        return userDetails;
    }

    /**
     * The credentials that prove the principal is correct. This is usually a password,
     * but could be anything relevant to the <code>AuthenticationManager</code>. Callers
     * are expected to populate the credentials.
     *
     * @return the credentials that prove the identity of the <code>Principal</code>
     */
    @Override
    public Object getCredentials() {
        return ssoVerifyDTO.getToken();
    }

    /**
     * The identity of the principal being authenticated. In the case of an authentication
     * request with username and password, this would be the username. Callers are
     * expected to populate the principal for an authentication request.
     * <p>
     * The <tt>AuthenticationManager</tt> implementation will often return an
     * <tt>Authentication</tt> containing richer information as the principal for use by
     * the application. Many of the authentication providers will create a
     * {@code UserDetails} object as the principal.
     *
     * @return the <code>Principal</code> being authenticated or the authenticated
     * principal after authentication.
     */
    @Override
    public Object getPrincipal() {
        return userDetails;
    }

    /**
     * Returns true if the specified subject is implied by this principal.
     *
     * <p>The default implementation of this method returns true if
     * {@code subject} is non-null and contains at least one principal that
     * is equal to this principal.
     *
     * <p>Subclasses may override this with a different implementation, if
     * necessary.
     *
     * @param subject the {@code Subject}
     * @return true if {@code subject} is non-null and is
     * implied by this principal, or false otherwise.
     * @since 1.8
     */
    @Override
    public boolean implies(Subject subject) {
        return super.implies(subject);
    }
}
